package com.lix.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lix.auth.AuthUser;
import com.lix.mapper.RoleMapper;
import com.lix.mapper.UserMapper;
import com.lix.pojo.model.Role;
import com.lix.pojo.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 自定义用户详细信息服务
 *  SpringSecurity认证时会调用此类来进行校验用户是否存在，存在返回用户信息。
 */
@Service
@Slf4j
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if (!StringUtils.hasLength(username)) {
            throw new UsernameNotFoundException("用户名岂能为空!");
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(user)) {
            throw new UsernameNotFoundException("用户名不存在或密码错误~~~");
        }
        if (user.getUserStatus().equals(2)) {
            throw new LockedException("账户已被锁定,认证失败");
        }

        // 查询用户角色
        List<Role> roleList = roleMapper.selectRoleByUserId(user.getUserId());
        Collection<GrantedAuthority> grantedAuthorities = CollectionUtils.isEmpty(roleList) ? new ArrayList<>(0) :
                roleList.stream().map(r -> new SimpleGrantedAuthority("ROLE_" + r.getRoleName()))
                        .collect(Collectors.toList());

        // 扩展权限：添加 Activiti 相关权限
        // 用户拥有角色 ACTIVITI_USER，候选组 MANAGER_TEAM
        Set<GrantedAuthority> authorities = new HashSet<>(grantedAuthorities);
        // 添加用户拥有角色 ACTIVITI_USER，才可以使用 ProcessRuntime/TaskRuntime，，，候选组 MANAGER_TEAM
        authorities.add(new SimpleGrantedAuthority("ROLE_ACTIVITI_USER"));
        authorities.add(new SimpleGrantedAuthority("GROUP_MANAGER_TEAM"));

        AuthUser authUser = new AuthUser(user.getUserId(), username, user.getPassword(), authorities);

        log.info("authUser--authUser--authUser--authUser----{}", JSONObject.toJSONString(authUser));
        return authUser;
    }
}
